from flask import Blueprint, request, current_app
from marshmallow import ValidationError

from config.database import db
from models.role import Role, role_schema
from utils.res_result import make_response
from utils.role_required import role_required
from sqlalchemy import or_

role_blueprint = Blueprint('role', __name__)


@role_blueprint.route('/roles')
@role_required("ADMIN")
def index():
    page_num = request.args.get('page', 1, type=int)  # 获取页码，默认为第一页
    page_size = request.args.get('pageSize', 20, type=int)  # 获取每页显示的记录数，默认为20
    role_name = request.args.get('name', '', type=str)
    status = request.args.get('status', '', type=str)

    query = Role.query

    if role_name:
        query = query.filter(Role.role_name.like(f'%{role_name}%'))
    if status:
        query = query.filter(Role.status == status)

    pagination = query.order_by(Role.role_name).paginate(page=page_num,
                                                         per_page=page_size,
                                                         error_out=False)
    roles = pagination.items

    return make_response(data={
        "items": [role.to_dict() for role in roles],
        "total": pagination.total
    })


@role_blueprint.route('/getAllRoleList', methods=['GET'])
@role_required("ADMIN")
def get_all_role_list():
    roles = Role.query.filter(Role.status == 1).order_by(Role.role_name).all()
    return make_response(data=[role.to_dict() for role in roles])


@role_blueprint.route('/', methods=['POST'])
@role_required("ADMIN")
def add_role():
    try:
        data = request.get_json()
        current_app.logger.info(data)
        role = role_schema.load(data)

        existing_role = Role.query.filter(
            (Role.role_name == role.role_name) | (Role.role_value == role.role_value)).first()
        if existing_role:
            return make_response(code=1, message="Role name or role value already exists", status=400)

        role.created_at = role.updated_at = db.func.now()
        db.session.add(role)
        db.session.commit()
        return make_response()
    except ValidationError as err:
        return make_response(code=1, message="Field validation failed", status=400)
    finally:
        db.session.close()


@role_blueprint.route('/<string:role_id>', methods=['PUT'])
@role_required("ADMIN")
def edit_role(role_id):
    try:
        data = request.get_json()
        current_app.logger.info(data)
        role = Role.query.get_or_404(role_id)

        # 检查修改后的role_name或role_value是否与其他角色（排除当前角色）冲突
        existing_role = Role.query.filter(
            or_(
                Role.role_name == data['roleName'],
                Role.role_value == data['roleValue']
            ),
            Role.id != role_id  # 排除当前正在编辑的角色
        ).first()

        if existing_role:
            return make_response(code=1, message="Role name or role value already exists", status=400)

        role_schema.load(data, instance=role, partial=True)
        db.session.commit()
        return make_response()
    except ValidationError as err:
        return make_response(code=1, message="Field validation failed", status=400)
    finally:
        db.session.close()


@role_blueprint.route('/setRoleStatus', methods=['POST'])
@role_required("ADMIN")
def set_role_status():
    try:
        data = request.get_json()
        role_id = data.get('id')
        new_status = data.get('status')

        current_app.logger.info('role_id: %s, new_status: %s', role_id, new_status)

        if new_status not in ['0', '1']:
            return make_response(code=1, message="Invalid status value", status=400)

        role = Role.query.get_or_404(role_id)
        role.status = new_status
        db.session.commit()

        return make_response()

    except ValidationError as err:
        return make_response(code=1, message="field validate failed", status=400)
    finally:
        db.session.close()


@role_blueprint.route('/<string:role_id>', methods=['DELETE'])
@role_required("ADMIN")
def delete_role(role_id):
    try:
        role = Role.query.get_or_404(role_id)
        db.session.delete(role)
        db.session.commit()
        return make_response()
    except ValidationError as err:
        return make_response(code=1, message="field validate failed", status=400)
    finally:
        db.session.close()


@role_blueprint.route('/existRoleName', methods=['POST'])
@role_required("ADMIN")
def exist_role():
    role_name = request.json.get('roleName')
    role_id = request.json.get('roleId', None)

    if role_id:
        count = Role.query.filter(Role.role_name == role_name, Role.id != role_id).count()
    else:
        count = Role.query.filter(Role.role_name == role_name).count()

    return make_response(data={"count": count})


@role_blueprint.route('/existRoleValue', methods=['POST'])
@role_required("ADMIN")
def exist_role_value():
    role_value = request.json.get('roleValue')
    role_id = request.json.get('roleId', None)

    if role_id:
        count = Role.query.filter(Role.role_value == role_value, Role.id != role_id).count()
    else:
        count = Role.query.filter(Role.role_value == role_value).count()

    return make_response(data={"count": count})
